import { Ref } from 'vue'

export type ColorType = 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error'
export type SizeType = 'xs' | 's' | 'm' | 'l' | 'xl'
export type PopPlacementType = 'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end'
export type ModalPlacementType = 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center-center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'
export type AlignType = 'left' | 'center' | 'right'
export type TriggerType = 'click' | 'hover' | 'none'
export type DirectionType = 'h' | 'v'
export type LayoutType = 'flex' | 'grid' | 'block'
export type KeyType = string | number | symbol

export interface PopModifier {
    name: string
    options: Record<string, any>
}

export interface FormBasePropsType {
    color?: ColorType
    disabled?: boolean
    size: SizeType
    sharp?: boolean
}

export interface InputPropsType<TValue, TRule extends RuleAll> extends FormBasePropsType {
    value: TValue
    rules?: (TRule | Rule_required | Rule_func)[]
    isInner?: boolean
}

export interface SelectPropsType {
    getDisabledFunc?: (a: any) => boolean
}

export type FormProvided = Ref<{
    color?: ColorType
    disabled?: boolean
    size: SizeType
    sharp?: boolean
    removeValidateFunc: (keyForForm: symbol) => void
    addValidateFunc: (keyForForm: symbol, validateFunc: () => Promise<void>) => void
    labelAlign?: AlignType
    myLabelWidth?: number
    addLabelWidth: (keyForFormItem: symbol, clientWidth: number) => void
    autoAlignLabel: boolean
    removeLabelWidth: (keyForFormItem: symbol) => void
}>

export type FormItemProvided = Ref<{
    color?: ColorType
    disabled?: boolean
    size: SizeType
    sharp?: boolean
    setDiffResult: (valid: boolean | undefined, text: string | undefined) => void
    setInputRequired: (required: boolean) => void
    setValidateResult: (valid: boolean | undefined, errorMessage: string | undefined) => void
}>

export interface PopupExposed {
    getTargetEl: () => HTMLElement
    getPopEl: () => HTMLElement
}

export interface DropdownButtonGroupExposed {
    hidePop: () => void
}

export interface FormExposed {
    validate: () => Promise<void>
}

interface RuleBase {
    errorMessage?: string
    delay?: number
}

export interface Rule_required extends RuleBase {
    name: 'required'
    value?: boolean
}

export interface Rule_minLength extends RuleBase {
    name: 'minLength'
    value: number
    boundary?: boolean
}

export interface Rule_maxLength extends RuleBase {
    name: 'maxLength'
    value: number
    boundary?: boolean
}

export interface Rule_pattern extends RuleBase {
    name: 'pattern'
    value: RegExp
}

export interface Rule_min extends RuleBase {
    name: 'min'
    value: number
    boundary?: boolean
}

export interface Rule_max extends RuleBase {
    name: 'max'
    value: number
    boundary?: boolean
}

export interface Rule_decimal extends RuleBase {
    name: 'decimal'
    value: number
}

export interface Rule_earliest extends RuleBase {
    name: 'earliest'
    value: Date
    boundary?: boolean
    format: string
}

export interface Rule_latest extends RuleBase {
    name: 'latest'
    value: Date
    boundary?: boolean
    format: string
}

export interface Rule_func extends RuleBase {
    name: 'func'
    value: (val: any) => Promise<[boolean, string?]> | [boolean, string?]
}

export type RuleAll = Rule_required | Rule_minLength | Rule_maxLength | Rule_pattern | Rule_min | Rule_max | Rule_decimal | Rule_earliest | Rule_latest | Rule_func
